﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management;
using System.Text;
using WMI.NET.Abstracts;
using WMI.NET.CIM;

namespace WMI.NET.ComputerSystemHardware.MassStorage
{
    /// <summary>
    /// The Win32_CDROMDrive WMI class represents a CD-ROM drive on a computer system running Windows. Be aware that the name of the drive does not correspond to the logical drive letter assigned to the device.
    /// </summary>
    public class Win32_CDROMDrive : CIM_CDROMDrive
    {

        private string _Drive;
        private Nullable<Boolean> _DriveIntegrity;
        private Nullable<UInt16> _FileSystemFlags;
        private Nullable<UInt32> _FileSystemFlagsEx;
        private string _Id;
        private string _Manufacturer;
        private Nullable<UInt32> _MaximumComponentLength;
        private Nullable<Boolean> _MediaLoaded;
        private string _MediaType;
        private string _MfrAssignedRevisionLevel;
        private string _RevisionLevel;
        private Nullable<UInt32> _SCSIBus;
        private Nullable<UInt16> _SCSILogicalUnit;
        private Nullable<UInt16> _SCSIPort;
        private Nullable<UInt16> _SCSITargetId;
        private Nullable<UInt16> _SerialNumber;
        private Nullable<UInt64> _Size;
        private Nullable<Double> _TransferRate;
        private string _VolumeName;
        private string _VolumeSerialNumber;

        /// <summary>
        /// Drive letter of the CD-ROM drive.
        /// Example: "d:\"
        /// </summary>
        public string Drive { get { return _Drive; } }

        /// <summary>
        /// If True, files can be accurately read from the CD device. This is achieved by reading a block of data twice and comparing the data against itself.
        /// </summary>
        public Nullable<Boolean> DriveIntegrity { get { return _DriveIntegrity; } }

        /// <summary>
        /// This property is obsolete. In place of this property, use FileSystemFlagsEx.
        /// </summary>
        public Nullable<UInt16> FileSystemFlags { get { return _FileSystemFlags; } }

        /// <summary>
        /// File system flags associated with the Windows CD-ROM drive. This parameter can be any combination of flags, but FS_FILE_COMPRESSION and FS_VOL_IS_COMPRESSED are mutually exclusive.
        /// </summary>
        public Nullable<UInt32> FileSystemFlagsEx { get { return _FileSystemFlagsEx; } } //TODO enum

        /// <summary>
        /// Drive letter that uniquely identifies this CD-ROM drive.
        /// Example: "d:\"
        /// </summary>
        public string Id { get { return _Id; } }

        /// <summary>
        /// Manufacturer of the Windows CD-ROM drive.
        /// Example: "PLEXTOR"
        /// </summary>
        public string Manufacturer { get { return _Manufacturer; } }

        /// <summary>
        /// Maximum length of a filename component supported by the Windows CD-ROM drive. A file name component the portion of a file name between backslashes. The value can be used to indicate that long names are supported by the specified file system. For example, for a FAT file system supporting long names, the function stores the value 255, rather than the previous 8.3 indicator. Long names can also be supported on systems that use the NTFS file system.
        /// Example: 255
        /// </summary>
        public Nullable<UInt32> MaximumComponentLength { get { return _MaximumComponentLength; } }

        /// <summary>
        /// If True, a CD-ROM is in the drive.
        /// </summary>
        public Nullable<Boolean> MediaLoaded { get { return _MediaLoaded; } }

        /// <summary>
        /// Type of media that can be used or accessed by this device.
        /// </summary>
        public string MediaType { get { return _MediaType; } } //TODO enum

        /// <summary>
        /// Firmware revision level that is assigned by the manufacturer.
        /// Windows Server 2003 and Windows XP:  This property is not available.
        /// </summary>
        public string MfrAssignedRevisionLevel { get { return _MfrAssignedRevisionLevel; } }

        /// <summary>
        /// Firmware revision level of the Windows CD-ROM drive.
        /// </summary>
        public string RevisionLevel { get { return _RevisionLevel; } }

        /// <summary>
        /// SCSI bus number for the disk drive.
        /// Example: 0
        /// </summary>
        public Nullable<UInt32> SCSIBus { get { return _SCSIBus; } }

        /// <summary>
        /// SCSI logical unit number (LUN) of the disk drive. The LUN is used to designate which SCSI controller is being accessed in a system with more than one controller being used. The SCSI device identifier is similar, but is the designation for multiple devices on one controller.
        /// Example: 0
        /// </summary>
        public Nullable<UInt16> SCSILogicalUnit { get { return _SCSILogicalUnit; } }

        /// <summary>
        /// SCSI port number of the disk drive.
        /// Example: 1
        /// </summary>
        public Nullable<UInt16> SCSIPort { get { return _SCSIPort; } }

        /// <summary>
        /// SCSI identifier number of the Windows CD-ROM drive.
        /// Example: 0
        /// </summary>
        public Nullable<UInt16> SCSITargetId { get { return _SCSITargetId; } }

        /// <summary>
        /// Number supplied by the manufacturer that identifies the physical media. Example: WD-WM3493798728.
        /// Windows Server 2003 and Windows XP:  This property is not available. 
        /// </summary>
        public Nullable<UInt16> SerialNumber { get { return _SerialNumber; } }

        /// <summary>
        /// Size of the disk drive.(Bytes) 
        /// </summary>
        public Nullable<UInt64> Size { get { return _Size; } }

        /// <summary>
        /// Transfer rate of the CD-ROM drive. A value of -1 indicates that the rate cannot be determined. When this happens, the CD is not in the drive. (KiloBytes per Second) 
        /// </summary>
        public Nullable<Double> TransferRate { get { return _TransferRate; } }

        /// <summary>
        /// Volume name of the Windows CD-ROM drive.
        /// </summary>
        public string VolumeName { get { return _VolumeName; } }

        /// <summary>
        /// Volume serial number of the media in the CD-ROM drive.
        /// Example: A8C3-D032
        /// </summary>
        public string VolumeSerialNumber { get { return _VolumeSerialNumber; } }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        public Win32_CDROMDrive(ManagementBaseObject mbo)
            : base(mbo)
        {
            _Drive = mbo.GetStringValue("Drive");
            _DriveIntegrity = mbo.GetBoolValue("DriveIntegrity");
            _FileSystemFlags = mbo.GetUshortValue("FileSystemFlags");
            _FileSystemFlagsEx = mbo.GetUIntValue("FileSystemFlagsEx");
            _Id = mbo.GetStringValue("Id");
            _Manufacturer = mbo.GetStringValue("Manufacturer");
            _MaximumComponentLength = mbo.GetUIntValue("MaximumComponentLength");
            _MediaLoaded = mbo.GetBoolValue("MediaLoaded");
            _MediaType = mbo.GetStringValue("MediaType");
            _MfrAssignedRevisionLevel = mbo.GetStringValue("MfrAssignedRevisionLevel");
            _RevisionLevel = mbo.GetStringValue("RevisionLevel");
            _SCSIBus = mbo.GetUIntValue("SCSIBus");
            _SCSILogicalUnit = mbo.GetUshortValue("SCSILogicalUnit");
            _SCSIPort = mbo.GetUshortValue("SCSIPort");
            _SCSITargetId = mbo.GetUshortValue("SCSITargetId");
            _SerialNumber = mbo.GetUshortValue("SerialNumber");
            _Size = mbo.GetUlongValue("Size");
            _TransferRate = mbo.GetDoubleValue("TransferRate");
            _VolumeName = mbo.GetStringValue("VolumeName");
            _VolumeSerialNumber = mbo.GetStringValue("VolumeSerialNumber");
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class GetWin32_CDROMDrives : Win32Collection<Win32_CDROMDrive>
    {

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ReadOnlyCollection<Win32_CDROMDrive> GetCollection()
        {
            List<Win32_CDROMDrive> tempCollection = new List<Win32_CDROMDrive>();

            foreach (var s in searcher.Get())
            {
                Win32_CDROMDrive tempListItem = new Win32_CDROMDrive(s);
                tempCollection.Add(tempListItem);
            }

            return tempCollection.AsReadOnly();
        }

        /// <summary>
        /// 
        /// </summary>
        public GetWin32_CDROMDrives() : base("SELECT * FROM Win32_CDROMDrive") { }

    }

}
